package com.scorpio.sdk.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.scorpio.common.exception.CustomException;
import com.scorpio.common.utils.StringUtils;
import com.scorpio.common.utils.http.HttpUtils;
import com.scorpio.common.utils.http.Request;
import com.scorpio.sdk.constant.ShunFengConstant;
import com.scorpio.sdk.dto.SFAddressModel;
import com.scorpio.sdk.dto.SFRouteRespsModel;
import com.scorpio.sdk.service.SFService;
import com.scorpio.system.service.ISysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;

import javax.annotation.PostConstruct;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.List;
import java.util.UUID;

@Service
public class SFServiceImpl implements SFService {

    @Autowired
    private ISysConfigService sysConfigService;

    @Override
    public String getMsgDigest(String timestamp, String msgData) {
        try {
            //客户校验码    使用顺丰分配的客户校验码
            String checkWord = sysConfigService.selectConfigByKey(ShunFengConstant.CONFIG_SM_PARTNER_SECRET);

            //将业务报文+时间戳+校验码组合成需加密的字符串(注意顺序)
            String toVerifyText = msgData + timestamp + checkWord;

            //因业务报文中可能包含加号、空格等特殊字符，需要urlEnCode处理
            toVerifyText = URLEncoder.encode(toVerifyText, "UTF-8");

            //进行Md5加密
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(toVerifyText.getBytes("UTF-8"));
            byte[] md = md5.digest();

            //通过BASE64生成数字签名
            String msgDigest = new BASE64Encoder().encode(md);
            return msgDigest;
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException("系统出错");
        }
    }

    @Override
    public JSONObject requestSFApi(String serviceCode, String msgData) {
        String timestamp = "" + System.currentTimeMillis();
        StringBuilder sb = new StringBuilder();
        sb.append("partnerID=");
        sb.append(sysConfigService.selectConfigByKey(ShunFengConstant.CONFIG_SM_PARTNER_ID));
        sb.append("&requestID=");
        sb.append(UUID.randomUUID().toString().replaceAll("-", ""));
        sb.append("&serviceCode=");
        sb.append(serviceCode);
        sb.append("&timestamp=");
        sb.append(timestamp);
        sb.append("&msgDigest=");
        sb.append(getMsgDigest(timestamp, msgData));
        sb.append("&msgData=");
        sb.append(msgData);

        String data = HttpUtils.request(new Request()
                .url(ShunFengConstant.SFAPI)
                .post()
                .initformUrlencoded()
                .body(sb.toString()));
        JSONObject json = JSONObject.parseObject(data);
        String apiResultCode = json.getString("apiResultCode");
        if ("A1000".equals(apiResultCode)) {
            return json.getJSONObject("apiResultData");
        } else {
            String errorMsg = json.getString("apiErrorMsg");
            if (StringUtils.isEmpty(errorMsg)) {
                throw new CustomException("系统出错");
            } else {
                throw new CustomException(errorMsg);
            }
        }
    }

    @Override
    public boolean validateWaybillno(String waybillNo) {
        JSONObject json = new JSONObject();
        json.put("waybillNo", waybillNo);
        String msgData = quertResult(ShunFengConstant.EXP_RECE_VALIDATE_WAYBILLNO, json.toJSONString());
        return "true".equals(msgData);
    }

    @Override
    public List<SFRouteRespsModel> searchRoutes(String number) {
        JSONArray trackingNumber = new JSONArray();
        trackingNumber.add(number);
        JSONObject json = new JSONObject();
        json.put("trackingType", "1");
        json.put("trackingNumber", trackingNumber);
        String msgData = quertResult(ShunFengConstant.EXP_RECE_SEARCH_ROUTES, json.toJSONString());
        JSONObject body  = JSONObject.parseObject(msgData);
        JSONArray routeResps = body.getJSONArray("routeResps");
        for (int i = 0; i < routeResps.size(); i++) {
            JSONObject item = routeResps.getJSONObject(i);
            if (number.equals(item.getString("mailNo"))) {
                JSONArray array = item.getJSONArray("routes");
                return JSONArray.parseArray(array.toJSONString(), SFRouteRespsModel.class);
            }
        }
        throw new CustomException("无效查询");
    }

    @Override
    public Double getSFFee(SFAddressModel destAddress, SFAddressModel srcAddress, Double weight) {
        JSONObject json = new JSONObject();
        json.put("businessType", "2");
        json.put("searchPrice", "1");

        json.put("destAddress", destAddress);
        json.put("srcAddress", srcAddress);

        if (weight != null && weight > 0) {
            json.put("weight", weight);
        }
        String msgData = quertResult(ShunFengConstant.EXP_RECE_QUERY_DELIVERTM, json.toJSONString());
        JSONObject msgDataJson = JSONObject.parseObject(msgData);
        double feeTotal = 0;
        JSONArray deliverTmDto = msgDataJson.getJSONArray("deliverTmDto");
        for (int i = 0; i < deliverTmDto.size(); i++) {
            JSONObject item = deliverTmDto.getJSONObject(i);
            Double fee = item.getDouble("fee");
            if (fee != null && fee > 0) {
                feeTotal += fee;
            }
        }
        return feeTotal;
    }


    //请求顺丰接口
    @Override
    public String quertResult(String serviceCode, String queryP) {
        JSONObject body = requestSFApi(serviceCode, queryP);
        Boolean success = body.getBoolean("success");
        if (success != null && success) {
            String msgData = body.getString("msgData");
            return msgData;
        } else {
            String errorMsg = body.getString("errorMsg");
            if (StringUtils.isEmpty(errorMsg)) {
                throw new CustomException("系统出错");
            } else {
                throw new CustomException(errorMsg);
            }
        }
    }
}
